package cn.biplam.back.sql.ddl;

import java.io.Serializable;
import java.util.ArrayList;

import cn.biplam.common.client.DbResource;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;

/**
 * 提供数据库表(Table)结构的语义模型
 * <ul>表包含的对象有：
 * <li> 字段
 * <li> 主键
 * <li> 外键
 * </ul> 
 * @author 	WangSong Mar 11, 2009 7:13:34 PM
 * @version 1.0
 */
public class Table implements Serializable{

	private static final long serialVersionUID = 7489816142206617361L;

	/**存储表的多个列结构(每个列结构包含一组字段)*/
	private KvMap<Integer, Field> fields=null;

	/**存储表的多个列结构(每个列结构包含一组主键)*/
	private PK mPK=null;
	/**存储表的多个列结构(每个列结构包含一组字段)*/
	public ArrayList<FK> FKs=null;
	/**存储表的多个列结构(每个列结构包含一组主键)*/
	public KvMap<String, Index> Indexs=null;

	/**存储表的列结构索引*/
	private Integer iColumns=0;
	/**表说明*/
	private String sComment=null;
	/**表逻辑名称*/
	private String sLogicName=null;
	/**表物理名称*/
	private String sPhysicalName=null;
	/**数据源信息*/
	private DbResource mDbResource;

	/**
	 * 构造方法 传入 表物理名称 初始化
	 * @param sPhysicalName	物理名称(非空,符合命名规范)
	 */
	public Table(String sPhysicalName,DbResource mDbResource) {
		this(sPhysicalName,null,mDbResource);
	}

	/**
	 * 构造方法 传入表的 物理名称、逻辑名称 初始化
	 * @param sLogicName		逻辑名称(为空则同物理名称)
	 * @param sPhysicalName		物理名称(非空,符合命名规范)
	 */
	public Table(String sPhysicalName,String sLogicName){
		this(sPhysicalName,sLogicName,null);
	}

	/**
	 * 构造方法 传入表的 物理名称、逻辑名称 初始化
	 * @param sLogicName		逻辑名称(为空则同物理名称)
	 * @param sPhysicalName		物理名称(非空,符合命名规范)
	 * @param mDbResource       表所属数据源
	 */
	public Table(String sPhysicalName,String sLogicName,DbResource mDbResource){
		this.mDbResource = mDbResource;
		this.setName(sPhysicalName, sLogicName);
		this.init();
	}

	/**
	 *  参数初始化
	 */
	private void init(){
		this.fields = new KvMap<Integer, Field>();
		this.FKs = new ArrayList<FK>();
		this.Indexs = new KvMap<String, Index>();
	}

	/**
	 * 返回Column的当前序号(0——?)
	 * @return Column的当前序号
	 */
	public Integer getColumnIndex() {
		return this.iColumns;
	}

	/**
	 * 返回逻辑名称
	 * @return 逻辑名称
	 */
	public String getLogicName() {
		if(sLogicName!=null && "null".equals(sLogicName.trim())){
			sLogicName = null;
		}
		return this.sLogicName;
	}

	/**
	 * 返回物理名称
	 * @return 物理名称
	 */
	public String getPhysicalName() {
		if(sPhysicalName!=null && "null".equals(sPhysicalName.trim())){
			sPhysicalName = null;
		}
		return this.sPhysicalName;
	}

	/**
	 * 放入Table的Structure对象
	 * @param mStructure	Table的内容
	 * @throws ErrorMessage
	 */
	public void put(Structure mStructure) throws ErrorMessage{
		throw new ErrorMessage("此方法已经停用");
	}

	/**
	 * 放入表字段  
	 * @param field 表字段对象
	 * @throws ErrorMessage
	 */
	public void put(Field field) throws ErrorMessage{
		this.fields.put(iColumns++,  field);
	}

	/**
	 * 设置表主键
	 * @param pk 表主键
	 */
	public void put(PK pk){
		this.mPK=pk;
	}

	/**
	 * 设置表外键 
	 * @param fk 外键
	 * @throws ErrorMessage
	 */
	public void put(FK fk) throws ErrorMessage{
		this.FKs.add(fk);
	}

	/**
	 * 设置表索引
	 * @param index   表索引
	 * @throws ErrorMessage
	 */
	public void put(Index index) throws ErrorMessage{
		this.Indexs.put(index.getPhysicalName(), index);
	}

	/**
	 * 设置Table的逻辑名称
	 * @param logicName	逻辑名称
	 */
	public void setLogicName(String logicName) {
		this.sLogicName = logicName;
	}

	/**
	 * 设置Table的物理名称和逻辑名称
	 * @param physicalName	物理名称
	 * @param logicName		逻辑名称
	 */
	public void setName(String physicalName,String logicName){
		this.setPhysicalName(physicalName);
		this.setLogicName(logicName);
	}

	/**
	 * 设置Table的物理名称
	 * @param physicalName	物理名称
	 */
	public void setPhysicalName(String physicalName) {
		this.sPhysicalName = physicalName;
	}

	/**
	 * 返回SQL语法表示的表的通用定义语句
	 * @return SQL语法表示的表的通用定义语句
	 */
	public String toString(){
		return null;
	}

	/**
	 * 返回Table的说明
	 * @return	Table的说明
	 */
	public String getComment() {
		return this.sComment;
	}

	/**
	 * 设置Table的说明
	 * @param comment
	 */
	public void setComment(String comment) {
		this.sComment = comment;
	}

	/**
	 * 返回数据源信息
	 * @return	数据源
	 */
	public DbResource getDbResource(){
		return this.mDbResource;
	}


	/**
	 * 返回指定位置的字段
	 * @return the fields
	 */
	public KvMap<Integer, Field> getField() {
		return this.fields;
	}


	/**
	 * 放入一个字段
	 * @param 	Field
	 * @throws ErrorMessage 
	 */
	public void putFields(Field field) throws ErrorMessage {
		this.fields.put(this.iColumns++, field);
	}


	/**
	 * 设置主键
	 * @return the mPK
	 */
	public PK getPK() {
		return this.mPK;
	}


	/**
	 * 返回主键
	 * @param mpk the mPK to set
	 */
	public void setPK(PK mPK) {
		this.mPK = mPK;
	}


	/**
	 * 返回外键集合
	 * @return the fKs
	 */
	public ArrayList<FK> getFKSet() {
		return this.FKs;
	}


	/**
	 * @param ks the fKs to set
	 * @throws ErrorMessage 
	 */
	public void putFK(FK mFK) throws ErrorMessage {
		this.FKs.add( mFK);
	}


	/**
	 * @return the indexs
	 */
	public KvMap<String, Index> getIndexs() {
		return Indexs;
	}


	/**
	 * @param indexs the indexs to set
	 */
	public void setIndexs(KvMap<String, Index> indexs) {
		Indexs = indexs;
	}


	/**
	 * @return the fields
	 */
	public KvMap<Integer, Field> getFieldSet() {
		return fields;
	}

}
